package com.supermarket.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.supermarket.dto.StockPageQueryDto;
import com.supermarket.entity.Stock;
import com.supermarket.exception.BusinessException;
import com.supermarket.mapper.StockMapper;
import com.supermarket.service.StockService;
import com.supermarket.utils.PageResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
@Slf4j
@RequiredArgsConstructor
public class StockServiceImpl implements StockService {

    private final StockMapper stockMapper;

    @Override
    public PageResult list(StockPageQueryDto stockPageQueryDto) {
        // 设置默认分页参数
        if (stockPageQueryDto.getPage() == null) {
            stockPageQueryDto.setPage(1);
        }
        if (stockPageQueryDto.getPageSize() == null) {
            stockPageQueryDto.setPageSize(10);
        }

        PageHelper.startPage(stockPageQueryDto.getPage(), stockPageQueryDto.getPageSize());
        Page<Stock> page = (Page<Stock>) stockMapper.list(stockPageQueryDto);

        return new PageResult(page.getTotal(), page.getResult());
    }

    @Override
    public Stock getById(Long id) {
        Stock stock = stockMapper.getById(id);
        if (stock == null) {
            throw new BusinessException("库存记录不存在");
        }
        return stock;
    }

    @Override
    public Stock getByProductId(Long productId) {
        return stockMapper.getByProductId(productId);
    }

    @Override
    @Transactional
    public void save(Stock stock) {
        // 校验数据
        checkStockData(stock);

        // 设置默认值
        stock.setLocked(0);
        stock.setCreateTime(LocalDateTime.now());
        stock.setUpdateTime(LocalDateTime.now());

        stockMapper.insert(stock);
    }

    @Override
    @Transactional
    public void update(Stock stock) {
        // 校验库存记录是否存在
        getById(stock.getId());

        // 校验数据
        checkStockData(stock);

        stock.setUpdateTime(LocalDateTime.now());
        stockMapper.update(stock);
    }

    @Override
    @Transactional
    public void delete(Long id) {
        // 校验库存记录是否存在
        Stock stock = getById(id);

        // 检查是否有锁定的库存
        if (stock.getLocked() > 0) {
            throw new BusinessException("该商品有锁定的库存，无法删除");
        }

        stockMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void updateQuantity(Long id, Integer quantity) {
        // 校验库存记录是否存在
        Stock stock = getById(id);

        // 校验数量
        if (quantity < stock.getLocked()) {
            throw new BusinessException("库存数量不能小于已锁定数量");
        }

        stockMapper.updateQuantity(id, quantity);
    }

    @Override
    @Transactional
    public void updateLocked(Long id, Integer locked) {
        // 校验库存记录是否存在
        Stock stock = getById(id);

        // 校验锁定数量
        if (locked > stock.getQuantity()) {
            throw new BusinessException("锁定数量不能大于库存数量");
        }

        stockMapper.updateLocked(id, locked);
    }

    /**
     * 校验库存数据
     */
    private void checkStockData(Stock stock) {
        if (stock.getQuantity() == null || stock.getQuantity() < 0) {
            throw new BusinessException("库存数量不能小于0");
        }

        if (stock.getProductId() == null) {
            throw new BusinessException("必须指定商品");
        }
    }
}